package ds.safelock.io;

/**
 * This class provides methods to write/append/read binary data from/to a given file
 * @author David Silva
 * @version 1.0
 */
public class FileHelper {
	
	/**
	 * Appends data to the given destination file
	 * @param dest destination file path
	 * @param data data to be appended
	 * @throws IOException if any error occurs while writing the data
	 */
	public static void append(String dest, byte[] data) throws java.io.IOException
	{
		store(dest,true,data);
	}

	/**
	 * Writes data to the given destination file
	 * if the file already exists, all his content will be lost (see append())
	 * @param dest destination file path
	 * @param data data to be written
	 * @throws IOException if any error occurs while writing the data
	 */
	public static void write(String dest, byte[] data) throws java.io.IOException
	{
		store(dest,false,data);
	}

	/**
	 * Reads the content from a given source file
	 * @param src source file path
	 * @return byte array containing the file content
	 * @throws FileNotFoundException if the source file doesn't exist
	 * @throws IOException if any error occurs while retrieving the file content
	 */
	public static byte[] read(String src) throws java.io.FileNotFoundException, 
												 java.io.IOException
	{
		//init both streams
		final java.io.FileInputStream fis = new java.io.FileInputStream(src);
		final java.io.DataInputStream dis = new java.io.DataInputStream(fis);

		//writes the file content into a data byte[]  
		java.util.ArrayList<Byte> data = new java.util.ArrayList<Byte>();
		for(;;)
			try { data.add(data.size(),dis.readByte()); }
		catch (java.io.EOFException e) { break; } //we reach the end of file

		//close both streams
		dis.close();
		fis.close();

		//return the proper data
		byte[] _data = toArray(data);
		data.clear();
		data = null;

		return _data;
	}


	private static void store(String dest, boolean append, byte[] data) throws java.io.IOException
	{
		//ensures that the file exists
		java.io.File f = new java.io.File(dest);
		if (f.exists() && !append)
			f.delete();
		else
			f.createNewFile();
		f = null;
		
		//init both streams
		final java.io.FileOutputStream fos;
		try { fos = new java.io.FileOutputStream(dest); }
		catch (java.io.FileNotFoundException e) { throw new java.io.IOException("Unable to create file "+dest); } //will never happen, unless we're really luckyyy
		final java.io.DataOutputStream dos = new java.io.DataOutputStream(fos);
		//writes the data to the specified file
		dos.write(data);
		
		//close both streams
		dos.close();
		fos.close();

	}
		
	private static byte[] toArray(java.util.ArrayList<Byte> data)
	{
		final byte[] _data = new byte[data.size()];
		int index = 0;
		for (byte b : data)
			_data[index++]=b;
		return _data;
	}
}
